<template>
  <div class="o-i18n-selector">
    <AutoComplete
      v-model="value"
      :data="i18nArr"
      :title="value"
      transfer
      :disabled="disabled || isDisabled"
      ref="auto"
      :class="'align-' + align"
      :placeholder="infotip"
      @on-focus="onFocus"
      @on-blur="onBlur"
      @on-change="onChange"
      @on-search="searchI18nContent"
      @on-select="getI18nContent"
      @on-enter="onEnter"
      @mouseleave="onMouseleave"
      @mouseenter="onMouseenter"
    ></AutoComplete>
    <Icon class="i18n-icon" type="ios-globe-outline" @click="openI18n"></Icon>
    <div
      class="item-render"
      v-show="(params ? (params.property ? true : false) : true) && showText"
    >
      <Tooltip :content="value" theme="light">
        <span class="i18n-render">{{ $srv.getI18nBySrv(value) }}</span>
      </Tooltip>
    </div>
  </div>
</template>
<script lang="ts">
import { Input, AutoComplete } from 'view-design';
import { Tsrv, T_srv, ifs, vue } from '@/services';

@T_srv.comp
export default class oI18nSelector extends vue {
  /**
   * props
   */
  @T_srv.prop() renderOpts: any;

  @T_srv.prop() params: any;

  @T_srv.prop({
    required: false,
    default: false
  })
  disabled: boolean;

  @T_srv.prop({
    required: false,
    default: ''
  })
  placeholder: string;

  /* 父组件compBoxInfo */
  @T_srv.prop({
    required: false,
    type: Object,
    default: null
  })
  compBoxInfo: ifs.I_compBoxInfo;

  /* 组件名 */
  private G_compName: string = 'oI18nSelector';

  /* 组件箱信息对象 */
  private GT_compBoxInfo: ifs.I_compBoxInfo;

  /* 组件箱对象 */
  private GT_compBox: ifs.I_compBox;

  /* 组件箱识别ID */
  private G_compID: string;

  private value = null;

  private tsrv = Tsrv;

  private i18nData = [];

  private i18nArr = [];

  private showText = true;

  private startValue = null;

  private isDisabled: boolean = false;

  private align: string = 'left';

  private isInTable: boolean = false;

  get infotip() {
    if (this.placeholder) {
      return this.placeholder;
    }
    if (this.renderOpts?.props?.placeholder) {
      return this.renderOpts.props.placeholder;
    }
    return '';
  }

  // 是否为table内的组件
  /**
   * data
   */
  @T_srv.watch('params')
  onParamsChange() {
    this.setValue();
    this.initProps();
  }

  @T_srv.watch('renderOpts', { deep: true })
  onRenderOptsChange() {
    this.initProps();
  }

  @T_srv.watch('disabled')
  onDisabledChange(val: boolean) {
    this.isDisabled = val;
  }

  @T_srv.model('model-change', { type: String }) modelvalue: string | null;

  @T_srv.watch('modelvalue')
  onValueChange(val: string | null) {
    this.setValue(val);
  }

  created() {
    this.GT_compBoxInfo = Tsrv.getCompInfo(this.compBoxInfo);
    this.G_compID = this.GT_compBoxInfo.compID;
    this.GT_compBox = this.GT_compBoxInfo.TcompBox;
    this.isInTable = !!this.params;
  }

  mounted() {
    /* 向父组件发送实例 */
    this.$emit('compBoxInfo', this.GT_compBoxInfo);
    this.GT_compBox.addCompMergeName(this.G_compID, this.G_compName, this);
    this.initProps();
    this.setValue();
    this.addCustomEvents();
  }

  beforeDestroy() {
    this.i18nData = [];
    this.i18nArr = [];
    this.destroyCustomEvents();
  }

  destroyed() {
    /* 注册组件销毁 */
    this.GT_compBox.removeCompMergeName(this.G_compID, this.G_compName);

    /* 如果父组件传入的compBoxInfo则删除本文件产生的引用,反之是本组件产生的ID统一删除 */
    if (Tsrv.utils.isEmpty(this.compBoxInfo)) {
      this.GT_compBox.removeCompsWithCompID(this.G_compID);
    } else {
      this.GT_compBox.removeCompsMergeName(this.G_compID, [
        `'${this.G_compName}'`
      ]);
    }
    /* 如果是动态组件可能会关闭全局compBox */
    // this.GT_compBox = null;
  }

  /**
   * init 初始化
   */
  private initProps() {
    if (this.isInTable) {
      this.isDisabled = this.renderOpts.props.disabled;
      if (!this.params.property) {
        this.align = this.params.column.align;
      } else {
        const items = this.params.$form.items;
        const find = Tsrv.utils.find(
          items,
          el => el.field === this.params.propertyvalue
        );
        if (find) {
          this.align = find.align || 'left';
        }
      }
    }
  }

  public focus() {
    ((this.$refs.auto as AutoComplete).$refs.input as Input).focus();
    (((this.$refs.auto as AutoComplete).$refs.input as Input)
      .$el as HTMLInputElement).click();
  }

  public resetValue() {
    this.setValue('');
    this.setTableValue(null);
  }

  // 选择i18n
  private getI18nContent(val) {
    if (val) {
      val = val.trim();
      this.value = val;
      this.setTableValue(val);
      this.emitEvent('dochange');
      this.emitEvent('blur');
    }
  }

  // 搜索i18n
  private searchI18nContent(val) {
    if (this.i18nData.length === 0) {
      const loc = this.$i18n.messages;
      const i18nContent = loc[Object.keys(loc)[0]].i18n;
      this.i18nData = Object.keys(i18nContent);
      this.i18nArr = this.i18nData.slice(0, 10);
    } else {
      if (Tsrv.utils.isString(val)) {
        this.i18nArr = this.i18nData.filter(el => el.indexOf(val) > -1);
      }
    }
  }

  setValue(val: string | undefined = undefined) {
    if (this.isInTable) {
      if (this.params.property) {
        this.value =
          val !== undefined
            ? val
            : this.params.data[this.params.property] === null
            ? ''
            : this.params.data[this.params.property];
      } else {
        this.value =
          val !== undefined
            ? val
            : this.params.row[this.params.column.property] === null
            ? ''
            : this.params.row[this.params.column.property];
      }
    } else {
      this.value = val || this.modelvalue;
      this.showText = this.value !== '' && !!Tsrv.getI18nBySrv(this.value);
    }
  }

  setTableValue(val: string | null) {
    if (this.isInTable) {
      if (this.params.property) {
        this.params.data[this.params.property] = val === null ? null : val;
      } else {
        this.params.row[this.params.column.property] =
          val === null ? null : val;
      }
    } else {
      this.emitEvent('change');
      this.$emit('model-change', val);
    }
  }

  // 打开i18n
  openI18n() {
    if (!this.isDisabled) {
      const name = this.isInTable
        ? this.params.property
          ? this.params.data[this.params.property]
          : this.params.row[this.params.column.property]
        : this.value;
      this.startValue = this.getValue();

      Tsrv.utils
        .createModal('o-i18n-panel', {
          name
        })
        .then(data => {
          if (data) {
            const d: string = data.trim();
            if (this.isInTable) {
              this.setTableValue(d);
              this.setValue();
              this.emitEvent('change');
              if (this.startValue !== this.getValue()) {
                this.emitEvent('dochange');
              }
            } else {
              this.setValue();
              this.emitEvent('change');
              this.$emit('model-change', d);
              this.emitEvent('blur');
            }
          }
        });
    }
  }

  onFocus(e) {
    if (!this.isDisabled) {
      if (this.isInTable) {
        if (this.params.property) {
          this.showText = false;
        }
      } else {
        this.showText = false;
      }
    }
    this.startValue = this.getValue();
    this.emitEvent('focus');
  }

  onBlur(e) {
    if (!this.isDisabled) {
      if (this.isInTable) {
        if (this.params.property) {
          this.showText = true;
        }
      } else {
        this.value = this.value.trim();
        this.showText = this.value !== '' && !!Tsrv.getI18nBySrv(this.value);
      }
    }
    this.emitEvent('blur');
    if (this.startValue !== this.getValue()) {
      this.emitEvent('dochange');
    }
  }

  // 输入i18n
  onChange(e) {
    if (this.isInTable) {
      if (e === '') {
        this.setTableValue(null);
      } else {
        if (Tsrv.utils.isContainChinese(e)) {
          this.setTableValue(null);
        } else {
          this.setTableValue(e);
        }
      }
    } else {
      if (Tsrv.utils.isContainChinese(e)) {
        this.setTableValue(null);
      } else {
        this.setTableValue(e);
      }
    }
  }

  onEnter(e) {
    this.emitEvent('enter');
  }

  onMouseleave(e) {
    this.emitEvent('mouseleave');
  }

  onMouseenter(e) {
    this.emitEvent('mouseenter');
  }

  getValue() {
    if (this.isInTable) {
      return this.params.property
        ? this.params.data[this.params.property]
        : this.params.row[this.params.column.property];
    }
    return this.value;
  }

  emitEvent(event: string) {
    if (this.isInTable) {
      const ev = this.renderOpts.events;
      // 深拷贝有问题
      // const params = Tsrv.utils.clone(this.params);
      const params = Tsrv.utils.cloneNoMatchVue(this.params, true);
      params.from = 'i18n';
      for (const action in ev) {
        if (ev[action] && action === `on-${event}`) {
          // ev[action](params);
          ev[action](params, event);
        }
      }
    } else {
      this.$emit(`on-${event}`, this.value);
    }
  }

  private addCustomEvents() {
    ((this.$refs.auto as AutoComplete)
      .$el as HTMLInputElement).addEventListener(
      'mouseenter',
      this.onMouseenter
    );
    ((this.$refs.auto as AutoComplete)
      .$el as HTMLInputElement).addEventListener(
      'mouseleave',
      this.onMouseleave
    );
  }

  private destroyCustomEvents() {
    ((this.$refs.auto as AutoComplete)
      .$el as HTMLInputElement).removeEventListener(
      'mouseenter',
      this.onMouseenter
    );
    ((this.$refs.auto as AutoComplete)
      .$el as HTMLInputElement).removeEventListener(
      'mouseleave',
      this.onMouseleave
    );
  }
}
</script>
<style scoped lang="scss">
.item-render {
  width: calc(100% - 30px);
  position: absolute;
  top: 1px;
  left: 1px;
  padding: 0 2px 0 6px;
  height: calc(100% - 2px);
  display: flex;
  align-items: center;
  border-radius: 3px;
  overflow: hidden;
  pointer-events: none;
  background-color: #fff;
  word-break: keep-all;
}
.o-i18n-selector ::v-deep {
  position: relative;
  .ivu-select-dropdown {
    max-height: 300px;
  }
  .ivu-input {
    padding-right: 30px !important;
  }
  .i18n-icon {
    position: absolute;
    right: 0;
    top: 0;
    height: 100%;
    width: 30px;
    line-height: 30px;
    font-size: 16px;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .i18n-render {
    white-space: nowrap;
  }
}
</style>
